//********************************************************************************************************************//
//ORGANIZATION:
//AUTHOR: bpeng(bogers.peng@gmail.com)
//SUMMARY:
//********************************************************************************************************************//
#ifndef NATIVE_SYSTEM_BASE_DUAD_H
#define NATIVE_SYSTEM_BASE_DUAD_H

#ifndef NATIVE_SYSTEM_BASE_OBJECT_H
#include "System/Base/Object.h"
#endif
#ifndef NATIVE_SYSTEM_BASE_EQUALTO_H
#include "System/Base/EqualTo.h"
#endif

namespace Native { namespace System
{
    //****************************************************************************************************************//
    //CDuad
    //
    //****************************************************************************************************************//
    template<typename _TLeft, typename _TRight>
    class NATIVE_LIBRARY_EXPORT CDuad :
        public CObject,
        public IEqualTo<CDuad<_TLeft, _TRight>>
    {
        NATIVE_DECLARE_OBJECT;

        NATIVE_REDEFINE(public, _TLeft, TLeft, T_LEFT);
        NATIVE_REDEFINE(public, _TRight, TRight, T_RIGHT);
        NATIVE_REDEFINE(public, CDuad<TLeft COMMA TRight>, Class, CLASS);

        NATIVE_DECLARE_PROPERTY(public, public, TLeft, Left, _left);
        NATIVE_DECLARE_PROPERTY(public, public, TRight, Right, _right);

    public:
        CDuad()
        {};

        CDuad(CLASS& that) :
            CObject(that),
            _left(that._left),
            _right(that._right)
        {};

        CDuad(CLASS&& that) :
            CObject(that),
            _left(that._left),
            _right(that._right)
        {};

        CDuad(T_LEFT& left, T_RIGHT& right) :
            _left(left),
            _right(right)
        {};

        CDuad(const pair<TLeft,TRight>& pair) :
            _left(pair.first),
            _right(pair.second)
        {};

        virtual ~CDuad()
        {};
        
        virtual bool operator==(CLASS& rvalue) const
        {
            return _left == rvalue._left && _right == rvalue._right;
        };

        virtual bool operator!=(CLASS& rvalue) const
        {
            return !operator==(rvalue);
        }

        void Set(TLeft left, TRight right)
        {
            _left = left;
            _right = right;
        }

        CLASS& operator=(CLASS& rvalue)
        {
            _left = rvalue._left;
            _right = rvalue._right;

            return *this;
        };

        CLASS& operator=(const pair<TLeft,TRight>& rvalue)
        {
            _left = rvalue.first;
            _right = rvalue.second;

            return *this;
        };
    };
}}

#endif